/* Copyright (c) 2004-2022 peigen.info. All rights reserved. */

package info.peigen.hotpot.common.core.util;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.google.common.math.LongMath;
import info.peigen.hotpot.common.core.enums.Number;
import info.peigen.hotpot.common.core.enums.Symbol;
import info.peigen.hotpot.common.core.lang.money.Money;

import java.math.RoundingMode;
import java.text.DecimalFormat;

/**
 * <b>(MoneyUtil)</b>
 *
 * @author Peigen
 * @version 1.0.0
 * @since 2021/4/22
 */
public class MoneyUtil {

    public final static String[] CH = {"", "", "拾", "佰", "仟", "万", "", "", "", "亿", "", "", "", "兆"};

    public final static String[] CHS_NUMBER = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};


    /**
     * 判断金额是否有钱(不为空 且 不等于0 )
     *
     * @param amount Money
     *
     * @return boolean
     */
    public static boolean hasMoney(Money amount) {
        return ObjectUtil.isNotNull(amount) && amount.getCent() > 0;
    }

    /**
     * 格式化金额为1,000,001.65的形式
     *
     * @param amount Money
     *
     * @return String
     */
    public static String format(Money amount) {
        Assert.isTrue(ObjectUtil.isNotNull(amount), "金额不能为null");

        DecimalFormat fmt    = new DecimalFormat("##,###,###,###,###.00");
        String        result = fmt.format(amount.getAmount().doubleValue());
        if (result.indexOf(Symbol.DOT.code()) == 0) {
            result = "0" + result;
        }
        return result;
    }

    /**
     * Money对象根据给定money取整
     * <p>举例:
     * roud(1234,50,UP)=1250<br>
     * roud(1234,50,DOWN)=1200<br>
     * roud(1300,50,UP)=1300<br>
     * roud(1300,50,DOWN)=1300<br>
     *
     * @param amount       需要取整的Money
     * @param roundAmount  取整数
     * @param roundingMode 取整策略
     *
     * @return Money
     */
    public static Money round(Money amount, Money roundAmount, RoundingMode roundingMode) {
        Assert.notNull(amount, "amount不能为空");
        Assert.notNull(roundAmount, "roundAmount不能为空");
        Assert.notNull(roundingMode, "roundingMode不能为空");
        long multiple = LongMath.divide(amount.getCent(), roundAmount.getCent(), roundingMode);
        long newCent  = LongMath.checkedMultiply(multiple, roundAmount.getCent());
        return amount.newMoneyWithSameCurrency(newCent);
    }

    /**
     * 传入数字金额字符串，返回数字金额对应的中文表示法 例如：壹仟陆佰柒拾万元零伍分
     *
     * @param amount 金额字符串
     *
     * @return 金额中文大写
     */
    public static String getChsNumber(Money amount) {
        Assert.isTrue(ObjectUtil.isNotNull(amount), "金额不能为null");

        if (amount.getCent() == 0) {
            return "零元";
        }
        String money = amount.getAmount().toString();
        String chs   = "";

        String tmpInt  = money.substring(0, money.indexOf("."));
        String tmpDown = money.substring(money.indexOf(".") + 1, money.length());

        char[]   tmpIntChar = tmpInt.toCharArray();
        String[] tmpChs     = new String[tmpIntChar.length];

        int tab = 0;
        for (int i = 0; i < tmpIntChar.length; i++) {

            tab = tmpIntChar.length - i - 1;

            if (tmpIntChar.length <= 5) {
                tmpChs[tab] = CHS_NUMBER[(int) Float.parseFloat(tmpIntChar[i] + ".0")];

                if (!StrUtil.equals(tmpChs[tab], "零")) {

                    // tmpIntChar.length - i 为数字所在的位数
                    chs = chs + tmpChs[tab] + CH[tmpIntChar.length - i];
                } else {// 当数字中有零时就在后加上零，如果超过１个以上的零也只加一个零
                    if (!chs.endsWith("零") && tab != 0) {
                        chs = chs + tmpChs[tab];

                    } else if (chs.endsWith("零") && tab == 0) {
                        chs = chs.substring(0, chs.length() - 1);
                    }

                }
            }

            // 　如果数字的位数大于５和小于９时
            if (tmpIntChar.length > 5 && tmpIntChar.length < 9) {
                tmpChs[tab] = CHS_NUMBER[(int) Float.parseFloat(tmpIntChar[i] + ".0")];

                // 如：123,1234分成两部分
                // 第１部分123：万以上亿以下
                if (tab >= 4) {
                    // 当前数字不是大小零时
                    if (!StrUtil.equals(tmpChs[tab], "零")) {
                        chs = chs + tmpChs[tab] + CH[tab - 3];

                        // 　当第１部分算完时在加上"万"
                        if (tab == 4) {
                            chs = chs + "万";
                        }

                    } else {
                        // 当前数字为大小"零"时
                        // 判断前一次形成在字符串结尾有没有零
                        // 　如果没有零就加上零
                        if (!chs.endsWith("零")) {
                            chs = chs + tmpChs[tab];

                        }

                        // 当第１部分算完时
                        if (tab == 4) {
                            // 　先判断字符串有没有零
                            // 　如果有零时就把零去掉再加上"万"
                            if (chs.endsWith("零")) {
                                chs = chs.substring(0, chs.length() - 1);
                                chs = chs + "万";
                            } else {
                                // 　如果没有零就直接加上"万"
                                chs = chs + "万";
                            }
                        }
                    }
                }

                // 如：123,1234分成两部分
                // 第１部分1234：万以下
                if (tab < 4) {
                    if (!StrUtil.equals(tmpChs[tab], "零")) {
                        // tmpIntChar.length - i 为数字所在的位数
                        chs = chs + tmpChs[tab] + CH[tmpIntChar.length - i];
                    } else {// 当数字中有零时就在后加上零，如果超过１个以上的零也只加一个零
                        if (!chs.endsWith("零") && tab != 0) {
                            chs = chs + tmpChs[tab];

                        }

                        if (chs.endsWith("零") && tab == 0) {
                            chs = chs.substring(0, chs.length() - 1);
                        }
                    }
                }
            }

            // 　如果数字的位数大于５和小于９时
            if (tmpIntChar.length >= 9 && tmpIntChar.length <= 12) {
                tmpChs[tab] = CHS_NUMBER[(int) Float.parseFloat(tmpIntChar[i] + ".0")];

                if (tab >= 8 && tab < 12) {
                    // 当前数字不是大小零时
                    if (!StrUtil.equals(tmpChs[tab], "零")) {
                        chs = chs + tmpChs[tab] + CH[tab - 7];

                        // 　当第１部分算完时在加上"万"
                        if (tab == 8) {
                            chs = chs + "亿";
                        }

                    } else {
                        // 当前数字为大小"零"时
                        // 判断前一次形成在字符串结尾有没有零
                        // 　如果没有零就加上零
                        if (!chs.endsWith("零")) {
                            chs = chs + tmpChs[tab];

                        }

                        // 当第１部分算完时

                        if (tab == 8) {
                            // 　先判断字符串有没有零
                            // 　如果有零时就把零去掉再加上"万"
                            if (chs.endsWith("零")) {
                                chs = chs.substring(0, chs.length() - 1);
                                chs = chs + "亿";
                            } else {
                                // 　如果没有零就直接加上"万"
                                chs = chs + "亿";
                            }
                        }
                    }
                }
                // 如：123,1234分成两部分
                // 第１部分123：万以上亿以下
                if (tab >= 4 && tab < 8) {
                    // 当前数字不是大小零时
                    if (!StrUtil.equals(tmpChs[tab], "零")) {
                        chs = chs + tmpChs[tab] + CH[tab - 3];

                        // 　当第１部分算完时在加上"万"
                        if (tab == 4) {
                            chs = chs + "万";
                        }

                    } else {
                        // 当前数字为大小"零"时
                        // 判断前一次形成在字符串结尾有没有零
                        // 　如果没有零就加上零
                        if (!chs.endsWith("零")) {
                            chs = chs + tmpChs[tab];

                        }

                        // 当第１部分算完时

                        if (tab == 4) {
                            // 　先判断字符串有没有零
                            // 　如果有零时就把零去掉再加上"万"
                            if (chs.endsWith("零")) {
                                chs = chs.substring(0, chs.length() - 1);

                                if (!chs.endsWith("亿")) {
                                    chs = chs + "万";
                                }
                            } else {
                                // 　如果没有零就直接加上"万"
                                if (!chs.endsWith("亿")) {
                                    chs = chs + "万";
                                }
                            }
                        }
                    }
                }

                // 如：123,1234分成两部分
                // 第１部分1234：万以下
                if (tab < 4) {

                    if (!StrUtil.equals(tmpChs[tab], "零")) {

                        // tmpIntChar.length - i 为数字所在的位数
                        chs = chs + tmpChs[tab] + CH[tmpIntChar.length - i];
                    } else {// 当数字中有零时就在后加上零，如果超过１个以上的零也只加一个零
                        if (!chs.endsWith("零") && tab != 0) {
                            chs = chs + tmpChs[tab];

                        }

                        if (chs.endsWith("零") && tab == 0) {
                            chs = chs.substring(0, chs.length() - 1);
                        }
                    }
                }
            }

            // 　如果数字的位数大于12和小于16时
            if (tmpIntChar.length > 12 && tmpIntChar.length <= 16) {
                tmpChs[tab] = CHS_NUMBER[(int) Float.parseFloat(tmpIntChar[i] + ".0")];

                if (tab >= 12 && tab < 16) {
                    // 当前数字不是大小零时
                    if (!StrUtil.equals(tmpChs[tab], "零")) {
                        chs = chs + tmpChs[tab] + CH[tab - 11];

                        // 　当第１部分算完时在加上"万"
                        if (tab == 12) {
                            chs = chs + "兆";
                        }

                    } else {
                        // 当前数字为大小"零"时
                        // 判断前一次形成在字符串结尾有没有零
                        // 　如果没有零就加上零
                        if (!chs.endsWith("零")) {
                            chs = chs + tmpChs[tab];

                        }

                        // 当第１部分算完时

                        if (tab == 12) {
                            // 　先判断字符串有没有零
                            // 　如果有零时就把零去掉再加上"万"
                            if (chs.endsWith("零")) {
                                chs = chs.substring(0, chs.length() - 1);
                                chs = chs + "兆";
                            } else {
                                // 　如果没有零就直接加上"万"
                                chs = chs + "兆";
                            }
                        }
                    }
                }

                if (tab >= 8 && tab < 12) {
                    // 当前数字不是大小零时
                    if (!StrUtil.equals(tmpChs[tab], "零")) {
                        chs = chs + tmpChs[tab] + CH[tab - 7];

                        // 　当第１部分算完时在加上"万"
                        if (tab == 8) {
                            chs = chs + "亿";
                        }

                    } else {
                        // 当前数字为大小"零"时
                        // 判断前一次形成在字符串结尾有没有零
                        // 　如果没有零就加上零
                        if (!chs.endsWith("零")) {
                            chs = chs + tmpChs[tab];

                        }

                        // 当第１部分算完时

                        if (tab == 8) {
                            // 　先判断字符串有没有零
                            // 　如果有零时就把零去掉再加上"万"
                            if (chs.endsWith("零")) {
                                chs = chs.substring(0, chs.length() - 1);
                                if (!chs.endsWith("兆")) {
                                    chs = chs + "亿";
                                }
                            } else {
                                // 　如果没有零就直接加上"万"
                                if (!chs.endsWith("兆")) {
                                    chs = chs + "亿";
                                }
                            }
                        }
                    }
                }
                // 如：123,1234分成两部分
                // 第１部分123：万以上亿以下
                if (tab >= 4 && tab < 8) {
                    // 当前数字不是大小零时
                    if (!StrUtil.equals(tmpChs[tab], "零")) {
                        chs = chs + tmpChs[tab] + CH[tab - 3];

                        // 　当第１部分算完时在加上"万"
                        if (tab == 4) {
                            chs = chs + "万";
                        }

                    } else {
                        // 当前数字为大小"零"时
                        // 判断前一次形成在字符串结尾有没有零
                        // 　如果没有零就加上零
                        if (!chs.endsWith("零")) {
                            chs = chs + tmpChs[tab];

                        }

                        // 当第１部分算完时

                        if (tab == 4) {
                            // 　先判断字符串有没有零
                            // 　如果有零时就把零去掉再加上"万"
                            if (chs.endsWith("零")) {
                                chs = chs.substring(0, chs.length() - 1);

                                if (!chs.endsWith("亿")) {
                                    if (!chs.endsWith("兆")) {
                                        chs = chs + "万";
                                    }
                                }
                            } else {
                                // 　如果没有零就直接加上"万"
                                if (!chs.endsWith("亿")) {
                                    if (!chs.endsWith("兆")) {
                                        chs = chs + "万";
                                    }
                                }
                            }
                        }
                    }
                }

                // 如：123,1234分成两部分
                // 第１部分1234：万以下
                if (tab < 4) {

                    if (!StrUtil.equals(tmpChs[tab], "零")) {

                        // tmpIntChar.length - i 为数字所在的位数
                        chs = chs + tmpChs[tab] + CH[tmpIntChar.length - i];
                    } else {// 当数字中有零时就在后加上零，如果超过１个以上的零也只加一个零
                        if (!chs.endsWith("零") && tab != 0) {
                            chs = chs + tmpChs[tab];

                        }

                        if (chs.endsWith("零") && tab == 0) {
                            chs = chs.substring(0, chs.length() - 1);
                        }
                    }
                }
            }

            // 　如果数字的位数大于16
            if (tmpIntChar.length > 16) {
                tmpChs[tab] = CHS_NUMBER[(int) Float.parseFloat(tmpIntChar[i] + ".0")];

                if (tab >= 12) {
                    chs = chs + tmpChs[tab];

                    // 　当第１部分算完时在加上"万"
                    if (tab == 12) {
                        chs = chs + "兆";
                    }

                }

                if (tab >= 8 && tab < 12) {
                    // 当前数字不是大小零时
                    if (!StrUtil.equals(tmpChs[tab], "零")) {
                        chs = chs + tmpChs[tab] + CH[tab - 7];

                        // 　当第１部分算完时在加上"万"
                        if (tab == 8) {
                            chs = chs + "亿";
                        }

                    } else {
                        // 当前数字为大小"零"时
                        // 判断前一次形成在字符串结尾有没有零
                        // 　如果没有零就加上零
                        if (!chs.endsWith("零")) {
                            chs = chs + tmpChs[tab];

                        }

                        // 当第１部分算完时

                        if (tab == 8) {
                            // 　先判断字符串有没有零
                            // 　如果有零时就把零去掉再加上"万"
                            if (chs.endsWith("零")) {
                                chs = chs.substring(0, chs.length() - 1);
                                if (!chs.endsWith("兆")) {
                                    chs = chs + "亿";
                                }
                            } else {
                                // 　如果没有零就直接加上"万"
                                if (!chs.endsWith("兆")) {
                                    chs = chs + "亿";
                                }
                            }
                        }
                    }
                }
                // 如：123,1234分成两部分
                // 第１部分123：万以上亿以下
                if (tab >= 4 && tab < 8) {
                    // 当前数字不是大小零时
                    if (!StrUtil.equals(tmpChs[tab], "零")) {
                        chs = chs + tmpChs[tab] + CH[tab - 3];

                        // 　当第１部分算完时在加上"万"
                        if (tab == 4) {
                            chs = chs + "万";
                        }

                    } else {
                        // 当前数字为大小"零"时
                        // 判断前一次形成在字符串结尾有没有零
                        // 　如果没有零就加上零
                        if (!chs.endsWith("零")) {
                            chs = chs + tmpChs[tab];

                        }

                        // 当第１部分算完时

                        if (tab == 4) {
                            // 　先判断字符串有没有零
                            // 　如果有零时就把零去掉再加上"万"
                            if (chs.endsWith("零")) {
                                chs = chs.substring(0, chs.length() - 1);

                                if (!chs.endsWith("兆")) {
                                    if (!chs.endsWith("亿")) {
                                        chs = chs + "万";
                                    }
                                }
                            } else {
                                // 　如果没有零就直接加上"万"
                                if (!chs.endsWith("兆")) {
                                    if (!chs.endsWith("亿")) {
                                        chs = chs + "万";
                                    }
                                }
                            }
                        }
                    }
                }

                // 如：123,1234分成两部分
                // 第１部分1234：万以下
                if (tab < 4) {

                    if (!StrUtil.equals(tmpChs[tab], "零")) {

                        // tmpIntChar.length - i 为数字所在的位数
                        chs = chs + tmpChs[tab] + CH[tmpIntChar.length - i];
                    } else {// 当数字中有零时就在后加上零，如果超过１个以上的零也只加一个零
                        if (!chs.endsWith("零") && tab != 0) {
                            chs = chs + tmpChs[tab];

                        }

                        if (chs.endsWith("零") && tab == 0) {
                            chs = chs.substring(0, chs.length() - 1);
                        }
                    }
                }
            }
        }

        char[] tmp = tmpDown.toCharArray();
        if (tmp.length == 1) {
            if (tmp[0] != Number.Zero.number()) {
                chs = chs + "元" + CHS_NUMBER[(int) Float.parseFloat(tmp[0] + ".0")] + "角整";
            } else {
                chs = chs + "元整";
            }
        } else {
            if (tmp[1] != Number.Zero.number() && tmp[0] != Number.Zero.number()) {
                if (chs.isEmpty()) {
                    chs = CHS_NUMBER[(int) Float.parseFloat(tmp[0] + ".0")] + "角"
                            + CHS_NUMBER[(int) Float.parseFloat(tmp[1] + ".0")] + "分";
                } else {
                    chs = chs + "元" + CHS_NUMBER[(int) Float.parseFloat(tmp[0] + ".0")] + "角"
                            + CHS_NUMBER[(int) Float.parseFloat(tmp[1] + ".0")] + "分";
                }
            } else if (tmp[1] != Number.Zero.number() && tmp[0] == Number.Zero.number()) {
                if (chs.isEmpty()) {
                    chs = CHS_NUMBER[(int) Float.parseFloat(tmp[1] + ".0")] + "分";
                } else {
                    chs = chs + "元零" + CHS_NUMBER[(int) Float.parseFloat(tmp[1] + ".0")] + "分";
                }
            } else if (tmp[1] == Number.Zero.number() && tmp[0] != Number.Zero.number()) {
                if (chs.isEmpty()) {
                    chs = CHS_NUMBER[(int) Float.parseFloat(tmp[0] + ".0")] + "角";
                } else {
                    chs = chs + "元" + CHS_NUMBER[(int) Float.parseFloat(tmp[0] + ".0")] + "角";
                }
            } else if (tmp[1] == Number.Zero.number() && tmp[0] == Number.Zero.number()) {
                chs = chs + "元整";
            }
        }
        return chs;
    }
}